package com.team.order.service.impl;

import com.team.order.constants.MqConstants;
import com.team.order.domain.Order;
import com.team.order.domain.RepairReservation;
import com.team.order.domain.dto.OrderSubmitDTO;
import com.team.order.mapper.AppOrderMapper;
import com.team.order.service.IAppOrderService;
import com.team.order.service.RepairService;
import com.team.order.utils.RedisIdWorker;
import com.team.order.utils.VerificationCodeUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author 梁国瑞
 * @version 1.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AppOrderServiceImpl implements IAppOrderService {

    private final AppOrderMapper appOrderMapper;
    private final RepairService repairService;
    private final RabbitTemplate rabbitTemplate;

    @Resource
    private final RedisIdWorker redisIdWorker;

    // private final ServiceItemClient serviceItemClient;

        @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = Exception.class)
    public int submitOrder(OrderSubmitDTO dto) {
        try {
            // 根据订单类型处理不同的业务流程
            if (dto.getOrderType() == null || "normal".equals(dto.getOrderType())) {
                // 普通订单流程
                return submitNormalOrder(dto);
            } else if ("repair".equals(dto.getOrderType())) {
                // 维修订单流程
                return submitRepairOrder(dto);
            } else if ("rescue".equals(dto.getOrderType())) {
                // 救援任务订单流程
                return submitRescueOrder(dto);
            } else {
                throw new RuntimeException("不支持的订单类型: " + dto.getOrderType());
            }
        } catch (Exception e) {
            throw new RuntimeException("提交订单失败", e);
        }
    }
    
    /**
     * 提交普通订单
     */
    @Transactional(rollbackFor = Exception.class)
    private int submitNormalOrder(OrderSubmitDTO dto) {
        // 1. 计算价格，调用service_item_service获取
        BigDecimal totalPrice = calculateTotalPrice(dto.getServiceItemIds());
        BigDecimal actualPrice = calculateActualPrice(totalPrice, dto.getCouponId());

        // 2. 生成核销码和二维码
        Object[] codeAndImage;
        try {
            codeAndImage = VerificationCodeUtil.generateCodeAndQRImage();
        } catch (Exception e) {
            throw new RuntimeException("生成核销码失败", e);
        }
        String verificationCode = (String) codeAndImage[0];
        String verificationImg = saveQRCodeImage((MultipartFile) codeAndImage[1]);

        // 3. 创建订单主表记录
        Order order = new Order();
        // 3.1 订单编号
        long orderId = redisIdWorker.nextId("order");
        order.setOrderNo(Long.toString(orderId));
        // 3.2 核销码
        order.setVerificationCode(verificationCode);
        // 3.3 核销码图片
        order.setVerificationImg(verificationImg);
        // 3.4 商户ID
        order.setMerchantId(dto.getMerchantId());
        // 3.5 下单用户ID
        order.setUserId(dto.getUserId());
        // 3.6 服务类别ID
        order.setServiceTypeId(dto.getServiceTypeId());
        // 3.7 预约时间
        order.setReservationTime(dto.getServiceTime());
        // 3.8 车辆ID
        order.setCarId(dto.getVehicleId());
        // 3.9 优惠券ID
        order.setCouponId(dto.getCouponId());
        // 3.10 服务总金额
        order.setTotalPrice(totalPrice);
        // 3.11 实付金额
        order.setPrice(actualPrice);
        // 3.12 支付状态
        order.setPayStatus(0L);
        // 3.13 订单状态
        order.setOrderStatus("0"); // 0-待接单
        // 3.14 是否门店自提
        order.setDoorService(dto.getDoorService());
        // 3.15 订单备注
        order.setOrderRemark(dto.getOrderRemark());
        // 3.16 订单类型
        order.setOrderType("normal"); // normal-普通订单

        // 4. 插入数据库
        int result = appOrderMapper.submitOrder(order);

        // 5. 发送延迟消息，检测订单是否超时
        rabbitTemplate.convertAndSend(
                MqConstants.DELAY_EXCHANGE_NAME,
                MqConstants.DELAY_ORDER_KEY,
                order.getId(),
                message -> {
                    message.getMessageProperties().setDelay(900000);
                    return message;
                });
        
        return result;
    }
    
    /**
     * 提交维修订单
     */
    @Transactional(rollbackFor = Exception.class)
    private int submitRepairOrder(OrderSubmitDTO dto) {
        // 验证维修预约记录ID
        if (dto.getRepairReservationId() == null) {
            throw new RuntimeException("维修订单必须提供维修预约记录ID");
        }
        
        // 1. 验证维修预约记录是否存在且状态正确
        boolean isValidReservation = repairService.validateReservation(dto.getRepairReservationId());
        if (!isValidReservation) {
            throw new RuntimeException("维修预约记录不存在或状态不正确");
        }
        
        // 2. 计算价格，调用service_item_service获取
        BigDecimal totalPrice = calculateTotalPrice(dto.getServiceItemIds());
        BigDecimal actualPrice = calculateActualPrice(totalPrice, dto.getCouponId());

        // 3. 生成核销码和二维码
        Object[] codeAndImage;
        try {
            codeAndImage = VerificationCodeUtil.generateCodeAndQRImage();
        } catch (Exception e) {
            throw new RuntimeException("生成核销码失败", e);
        }
        String verificationCode = (String) codeAndImage[0];
        String verificationImg = saveQRCodeImage((MultipartFile) codeAndImage[1]);

        // 4. 创建订单主表记录
        Order order = new Order();
        // 4.1 订单编号
        long orderId = redisIdWorker.nextId("order");
        order.setOrderNo(Long.toString(orderId));
        // 4.2 核销码
        order.setVerificationCode(verificationCode);
        // 4.3 核销码图片
        order.setVerificationImg(verificationImg);
        // 4.4 商户ID
        order.setMerchantId(dto.getMerchantId());
        // 4.5 下单用户ID
        order.setUserId(dto.getUserId());
        // 4.6 服务类别ID
        order.setServiceTypeId(dto.getServiceTypeId());
        // 4.7 预约时间
        order.setReservationTime(dto.getServiceTime());
        // 4.8 车辆ID
        order.setCarId(dto.getVehicleId());
        // 4.9 优惠券ID
        order.setCouponId(dto.getCouponId());
        // 4.10 服务总金额
        order.setTotalPrice(totalPrice);
        // 4.11 实付金额
        order.setPrice(actualPrice);
        // 4.12 支付状态
        order.setPayStatus(0L);
        // 4.13 订单状态
        order.setOrderStatus("0"); // 0-待接单
        // 4.14 是否门店自提
        order.setDoorService(dto.getDoorService());
        // 4.15 订单备注
        order.setOrderRemark(dto.getOrderRemark());
        // 4.16 订单类型
        order.setOrderType("repair"); // repair-维修订单
        // 4.17 关联维修预约记录ID
        order.setRepairReservationId(dto.getRepairReservationId());

        // 5. 插入数据库
        int result = appOrderMapper.submitOrder(order);
        
        // 6. 更新维修预约记录状态为已生成订单
        repairService.updateReservationStatus(dto.getRepairReservationId(), "ORDERED");
        
        return result;
    }

    /**
     * 提交救援任务订单
     */
    @Transactional(rollbackFor = Exception.class)
    private int submitRescueOrder(OrderSubmitDTO dto) {
        // 验证救援任务ID
        if (dto.getRescueTaskId() == null) {
            throw new RuntimeException("救援任务订单必须提供救援任务ID");
        }
        
        // 1. 验证救援任务记录是否存在且状态正确
        // TODO: 调用救援任务服务验证记录状态
        // boolean isValidRescueTask = rescueTaskService.validateRescueTask(dto.getRescueTaskId());
        // if (!isValidRescueTask) {
        //     throw new RuntimeException("救援任务记录不存在或状态不正确");
        // }
        
        // 2. 计算价格，调用service_item_service获取
        BigDecimal totalPrice = calculateTotalPrice(dto.getServiceItemIds());
        BigDecimal actualPrice = calculateActualPrice(totalPrice, dto.getCouponId());

        // 3. 生成核销码和二维码
        Object[] codeAndImage;
        try {
            codeAndImage = VerificationCodeUtil.generateCodeAndQRImage();
        } catch (Exception e) {
            throw new RuntimeException("生成核销码失败", e);
        }
        String verificationCode = (String) codeAndImage[0];
        String verificationImg = saveQRCodeImage((MultipartFile) codeAndImage[1]);

        // 4. 创建订单主表记录
        Order order = new Order();
        // 4.1 订单编号
        long orderId = redisIdWorker.nextId("order");
        order.setOrderNo(Long.toString(orderId));
        // 4.2 核销码
        order.setVerificationCode(verificationCode);
        // 4.3 核销码图片
        order.setVerificationImg(verificationImg);
        // 4.4 商户ID
        order.setMerchantId(dto.getMerchantId());
        // 4.5 下单用户ID
        order.setUserId(dto.getUserId());
        // 4.6 服务类别ID
        order.setServiceTypeId(dto.getServiceTypeId());
        // 4.7 预约时间
        order.setReservationTime(dto.getServiceTime());
        // 4.8 车辆ID
        order.setCarId(dto.getVehicleId());
        // 4.9 优惠券ID
        order.setCouponId(dto.getCouponId());
        // 4.10 服务总金额
        order.setTotalPrice(totalPrice);
        // 4.11 实付金额
        order.setPrice(actualPrice);
        // 4.12 支付状态
        order.setPayStatus(0L);
        // 4.13 订单状态
        order.setOrderStatus("0"); // 0-待接单
        // 4.14 是否门店自提
        order.setDoorService(dto.getDoorService());
        // 4.15 订单备注
        order.setOrderRemark(dto.getOrderRemark());
        // 4.16 订单类型
        order.setOrderType("rescue"); // rescue-救援任务订单
        // 4.17 关联救援任务ID
        order.setRescueTaskId(dto.getRescueTaskId());

        // 5. 插入数据库
        int result = appOrderMapper.submitOrder(order);
        
        // 6. 更新救援任务状态为已生成订单
        // TODO: 调用救援任务服务更新状态
        // rescueTaskService.updateRescueTaskStatus(dto.getRescueTaskId(), "ORDERED");
        
        return result;
    }
    
    /**
     * 计算服务总价
     */
    private BigDecimal calculateTotalPrice(List<Long> serviceItemIds) {
        // TODO: 调用服务项目微服务获取价格
        // 这里先返回模拟价格
        return new BigDecimal("100.00");
    }
    
    /**
     * 计算实付金额
     */
    private BigDecimal calculateActualPrice(BigDecimal totalPrice, Long couponId) {
        if (couponId == null) {
            return totalPrice;
        }
        
        // TODO: 调用优惠券微服务获取优惠金额
        // 这里先返回原价
        return totalPrice;
    }
    
    /**
     * 保存二维码图片
     */
    private String saveQRCodeImage(MultipartFile qrCodeImage) {
        // TODO: 实现文件上传逻辑，保存到文件服务器
        // 这里先返回模拟路径
        return "/upload/qrcode/" + System.currentTimeMillis() + ".png";
    }
    

}
